home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dutil / dupdate.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  14KB  |  690 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  DUPDATE.C
  9.  *
  10.  *  Distribution Update.
  11.  *
  12.  *  DUPDATE dist-dir dest-dir    [FORCE][QUIET][NODEL] [DISTFILE distfilename]
  13.  *  DUPDATE dist-file dest-dir    [FORCE][QUIET][NODEL] [DISTFILE distfilename]
  14.  */
  15.  
  16. #include <exec/types.h>
  17. #include <exec/lists.h>
  18. #include <exec/memory.h>
  19. #include <libraries/dos.h>
  20. #include <clib/dos_protos.h>
  21. #include <clib/exec_protos.h>
  22. #include <clib/alib_protos.h>
  23. #include <lib/version.h>
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28.  
  29. typedef struct MinList    MLIST;
  30. typedef struct List    LIST;
  31. typedef struct Node    NODE;
  32. typedef struct FileInfoBlock FIB;
  33.  
  34. MLIST    ScanList;    /*  scan list    */
  35. char    Buf[256];
  36.  
  37. char    *DistFileName = ".DistFiles";
  38. char    Force;
  39. char    Quiet;
  40. char    NoDel;
  41. char    Broke;
  42.  
  43. #ifdef _DCC
  44. IDENT("dupdate",".3");
  45. DCOPYRIGHT;
  46. #endif
  47.  
  48. typedef struct {
  49.     NODE    Node;    /*  link node        */
  50.     MLIST   List;    /*  if directory    */
  51.     FIB     *Fib[2];    /*  file/dir info   */
  52. } SNODE;
  53.  
  54. int brk(void);
  55. int main(short, char **);
  56. void Scan(long, MLIST *, int, int);
  57. void Update(long, long, MLIST *);
  58. SNODE *SNodeIn(FIB *, MLIST *, int, int);
  59. int CheckBroke(void);
  60. int getyn(char *, char *);
  61. int CopyFile(long, long, char *, char *, FIB *);
  62. int DeleteDir(char *);
  63. NODE *FindNode(LIST *, char *);
  64.  
  65. extern void *GetHead(void *);        /*     cr.lib funcs are registered */
  66. extern void *GetSucc(void *);
  67.  
  68. int
  69. brk()
  70. {
  71.     Broke = 1;
  72.     return(0);
  73. }
  74.  
  75. main(ac, av)
  76. short ac;
  77. char *av[];
  78. {
  79.     long slock = 0;
  80.     long dlock = 0;
  81.     char *sd = NULL;
  82.     char *dd = NULL;
  83.  
  84.     onbreak(brk);
  85.     NewList((LIST *)&ScanList);
  86.     if (ac < 3) {
  87.     puts("DUPDATE dist-dir dest-dir");
  88.     exit(1);
  89.     }
  90.     {
  91.     short i;
  92.     for (i = 1; i < ac; ++i) {
  93.         char *ptr = av[i];
  94.         if (stricmp(ptr, "DISTFILE") == 0) {
  95.         DistFileName = av[++i];
  96.         continue;
  97.         }
  98.         if (stricmp(ptr, "FORCE") == 0) {
  99.         Force = 1;
  100.         continue;
  101.         }
  102.         if (stricmp(ptr, "QUIET") == 0) {
  103.         Quiet = 1;
  104.         continue;
  105.         }
  106.         if (stricmp(ptr, "NODEL") == 0) {
  107.         NoDel = 1;
  108.         continue;
  109.         }
  110.         if (sd == NULL) {
  111.         sd = ptr;
  112.         continue;
  113.         }
  114.         if (dd == NULL) {
  115.         dd = ptr;
  116.         continue;
  117.         }
  118.         puts("Too many arguments!");
  119.         exit(1);
  120.     }
  121.     if (i > ac) {
  122.         puts("Expected argument to option");
  123.         exit(1);
  124.     }
  125.     }
  126. #ifdef DEBUG
  127.     puts("ScanA");
  128. #endif
  129.     slock = (long)Lock(sd, ACCESS_READ);
  130.     if (slock == NULL) {
  131.     printf("can't open %s\n", sd);
  132.     goto fail;
  133.     }
  134. #ifdef DEBUG
  135.     puts("ScanB");
  136. #endif
  137.     dlock = (long)Lock(dd, ACCESS_READ);
  138.     if (dlock == NULL) {
  139.     if (dlock = (long)CreateDir(dd)) {
  140.         UnLock(dlock);
  141.         dlock = (long)Lock(dd, ACCESS_READ);
  142.     }
  143.     }
  144. #ifdef DEBUG
  145.     puts("ScanC");
  146. #endif
  147.     if (dlock == NULL) {
  148.     printf("can't open/create %s\n", dd);
  149.     goto fail;
  150.     }
  151. #ifdef DEBUG
  152.     puts("Scan1");
  153. #endif
  154.     Scan(slock, &ScanList, 0, 0);
  155. #ifdef DEBUG
  156.     puts("Scan2");
  157. #endif
  158.     Scan(dlock, &ScanList, 1, 0);
  159. #ifdef DEBUG
  160.     puts("Update");
  161. #endif
  162.     Update(slock, dlock, &ScanList);
  163. fail:
  164. #ifdef DEBUG
  165.     puts("End");
  166. #endif
  167.     if (slock)
  168.     UnLock(slock);
  169.     if (dlock)
  170.     UnLock(dlock);
  171.     exit(1);
  172. }
  173.  
  174. /*
  175.  *  Scan.  Look for a .DistFiles file which contains a list of additional
  176.  *  files and files to not include.
  177.  */
  178.  
  179. void
  180. Scan(lock, list, side, ignoreNoMatch)
  181. long lock;
  182. MLIST *list;
  183. int side;
  184. int ignoreNoMatch;
  185. {
  186.     FIB *fib;
  187.     SNODE *sn;
  188.     FILE *fi;
  189.     char *distfile;
  190.     long savlock;
  191.     MLIST nolist;
  192.     short onlyFlag = 0;
  193.  
  194.     NewList((LIST *)&nolist);
  195.  
  196.     if (CheckBroke())
  197.     return;
  198.  
  199. #ifdef DEBUG
  200.     printf("Examine %08lx\n", lock);
  201. #endif
  202.  
  203.     fib = AllocMem(sizeof(FIB), MEMF_PUBLIC|MEMF_CLEAR);
  204.     if (Examine(lock, fib) && fib->fib_DirEntryType < 0)    /*    file    */
  205.     distfile = "";
  206.     else
  207.     distfile = DistFileName;
  208.  
  209. #ifdef DEBUG
  210.     puts("CD1");
  211. #endif
  212.     savlock = (long)CurrentDir(lock);
  213. #ifdef DEBUG
  214.     puts("CD2");
  215. #endif
  216.     if (side == 0 && (fi = fopen(distfile, "r"))) {
  217. #ifdef DEBUG
  218.     printf("open-success %s\n", distfile);
  219. #endif
  220.     while (fgets(Buf, sizeof(Buf), fi)) {
  221.         short len = strlen(Buf);
  222.         long lock2;
  223. #ifdef DEBUG
  224.         printf("BUF: %s\n", Buf);
  225. #endif
  226.  
  227.         if (CheckBroke())
  228.         break;
  229.         {
  230.         char *ptr;
  231.         if (strtok(Buf, " \t\n") == NULL)
  232.             continue;
  233.         if (ptr = strtok(NULL, " \t\n")) {  /*  NO keyword */
  234.             if (stricmp(ptr, "NO") == 0) {
  235.             NODE *node = malloc(sizeof(NODE) + strlen(Buf) + 1);
  236.             node->ln_Name = (char *)(node + 1);
  237.             strcpy(node->ln_Name, Buf);
  238.             AddTail((LIST *)&nolist, node);
  239.             continue;
  240.             }
  241.             if (stricmp(ptr, "ONLY") == 0)
  242.             onlyFlag = 1;
  243.         }
  244.         }
  245.         lock2 = (long)Lock(Buf, ACCESS_READ);
  246.         if (lock2 == NULL)
  247.         continue;
  248.         if (Examine(lock2, fib)) {
  249.         if (fib->fib_DirEntryType < 0) {
  250.             sn = SNodeIn(fib, list, side, ignoreNoMatch);
  251.             strcpy(sn->Fib[side]->fib_FileName, Buf);
  252.         } else {
  253.             if (sn = SNodeIn(fib, list, side, ignoreNoMatch)) {
  254.             strcpy(sn->Fib[side]->fib_FileName, Buf);
  255.             Scan(lock2, &sn->List, side, ignoreNoMatch);
  256.             /* Buf destroyed */
  257.             }
  258.         }
  259.         }
  260.         UnLock(lock2);
  261.     }
  262.     fclose(fi);
  263.     }
  264. #ifdef DEBUG
  265.     puts("Cont1");
  266. #endif
  267.     if (onlyFlag == 0 && Examine(lock, fib) && fib->fib_DirEntryType > 0) {
  268. #ifdef DEBUG
  269.     printf("Directory %s\n", fib->fib_FileName);
  270. #endif
  271.     while (ExNext(lock, fib)) {
  272.         if (CheckBroke())
  273.         break;
  274. #ifdef DEBUG
  275.         printf("Entry %s\n", fib->fib_FileName);
  276. #endif
  277.                             /*    ignore file */
  278.         if (FindNode((LIST *)&nolist, fib->fib_FileName))
  279.         continue;
  280.         if (fib->fib_DirEntryType < 0) {        /*    plain file  */
  281.         sn = SNodeIn(fib, list, side, ignoreNoMatch);
  282.         } else if (fib->fib_DirEntryType > 0) { /*    directory   */
  283.         if (sn = SNodeIn(fib, list, side, ignoreNoMatch)) {
  284.             long lock2;
  285.             if (lock2 = (long)Lock(fib->fib_FileName, ACCESS_READ)) {
  286.             Scan(lock2, &sn->List, side, ignoreNoMatch);
  287.             UnLock(lock2);
  288.             }
  289.         }
  290.         }
  291.     }
  292.     }
  293. #ifdef DEBUG
  294.     puts("scanend1");
  295. #endif
  296.     CheckBroke();
  297.     FreeMem(fib, sizeof(FIB));
  298.     CurrentDir(savlock);
  299. #ifdef DEBUG
  300.     puts("scanend2");
  301. #endif
  302.     {
  303.     NODE *node;
  304.     while (node = RemHead((LIST *)&nolist))
  305.         free(node);
  306.     }
  307. #ifdef DEBUG
  308.     puts("scanend3");
  309. #endif
  310. }
  311.  
  312. short tab = -4;
  313.  
  314. void
  315. Update(slock, dlock, list)
  316. long slock, dlock;
  317. MLIST *list;
  318. {
  319.     SNODE *sn;
  320.  
  321.     if (CheckBroke())
  322.     return;
  323.     tab += 4;
  324.  
  325. #ifdef DEBUG
  326.     puts("update1");
  327. #endif
  328.  
  329.     for (sn = GetHead(list); sn; sn = GetSucc(sn)) {
  330.  
  331. #ifdef DEBUG
  332.     puts("xupdate1");
  333. #endif
  334.     if (CheckBroke())
  335.         break;
  336. #ifdef DEBUG
  337.     puts("xupdate2");
  338. #endif
  339.  
  340.     if (Quiet == 0) {
  341.         short i;
  342.         for (i = tab; i; --i)
  343.         printf(" ");
  344.         if (sn->Fib[0])
  345.         printf("%-20s\t", sn->Node.ln_Name);
  346.         else
  347.         printf("%-20s\t", "-");
  348.  
  349.         if (sn->Fib[1])
  350.         printf("%-20s\t", sn->Node.ln_Name);
  351.         else
  352.         printf("%-20s\t", "-");
  353.     }
  354.  
  355. #ifdef DEBUG
  356.     puts("xupdate3");
  357. #endif
  358.  
  359.     if (sn->Fib[0] && sn->Fib[1]) {
  360.         if (strncmp(sn->Fib[0]->fib_Comment, "NODIST", 6) == 0)
  361.         sn->Fib[0] = NULL;
  362.     }
  363.  
  364. #ifdef DEBUG
  365.     puts("xupdate4");
  366. #endif
  367.  
  368.     if (sn->Fib[0] && sn->Fib[1]) {
  369. #ifdef DEBUG
  370.         puts("xupdate5");
  371. #endif
  372.  
  373.         if (sn->Fib[0]->fib_DirEntryType > 0) {
  374.         long savlock;
  375.         long locks;
  376.         long lockd;
  377.  
  378.         if (!Quiet)
  379.             puts("");
  380.         savlock = (long)CurrentDir(slock);
  381.         locks = (long)Lock(sn->Fib[0]->fib_FileName, ACCESS_READ);
  382.         CurrentDir(dlock);
  383.         lockd = (long)Lock(sn->Fib[1]->fib_FileName, ACCESS_READ);
  384.         CurrentDir(savlock);
  385.         if (locks && lockd)
  386.             Update(locks, lockd, &sn->List);
  387.         else
  388.             printf("software error %s\n", sn->Node.ln_Name);
  389.         if (locks)
  390.             UnLock(locks);
  391.         if (lockd)
  392.             UnLock(lockd);
  393.         } else {                /*    file    */
  394.         if (sn->Fib[0]->fib_Date == sn->Fib[1]->fib_Date && sn->Fib[0]->fib_Size == sn->Fib[1]->fib_Size) {
  395.             if (!Quiet)
  396.             puts("(ok)");
  397.         } else {
  398.             if (!Quiet)
  399.             puts("(update)");
  400.             CopyFile(slock, dlock, sn->Fib[0]->fib_FileName, sn->Fib[1]->fib_FileName, sn->Fib[0]);
  401.         }
  402.         }
  403.     } else if (sn->Fib[0]) {        /*    file/dir in dist-dir only */
  404. #ifdef DEBUG
  405.         puts("xupdate6");
  406. #endif
  407.         if (strncmp(sn->Fib[0]->fib_Comment, "NODIST", 6) == 0) {
  408.         if (!Quiet)
  409.             puts("(NODIST)");
  410.         continue;
  411.         }
  412.  
  413.         if (sn->Fib[0]->fib_DirEntryType < 0) {    /*  file    */
  414.         if (!Quiet) {
  415.             if (Force)
  416.             puts("(newfile, copy)");
  417.             else
  418.             puts("");
  419.         }
  420.         if (Force || getyn("Copy File %s ? ", sn->Node.ln_Name)) {
  421.             CopyFile(slock, dlock, sn->Fib[0]->fib_FileName, sn->Node.ln_Name, sn->Fib[0]);
  422.         }
  423.         } else {
  424.         if (!Quiet) {
  425.             if (Force)
  426.             puts("(newdir, copy)");
  427.             else
  428.             puts("");
  429.         }
  430.         if (Force || getyn("Copy Dir  %s ? ", sn->Node.ln_Name)) {
  431.             long locks;
  432.             long lockd;
  433.             long savlock;
  434.  
  435.             savlock = (long)CurrentDir(slock);
  436.             locks = (long)Lock(sn->Fib[0]->fib_FileName, ACCESS_READ);
  437.             CurrentDir(dlock);
  438.             if (lockd = (long)CreateDir(sn->Node.ln_Name)) {
  439.             UnLock(lockd);
  440.             lockd = (long)Lock(sn->Node.ln_Name, ACCESS_READ);
  441.             }
  442.             CurrentDir(savlock);
  443.             if (locks && lockd)
  444.             Update(locks, lockd, &sn->List);
  445.             if (locks)
  446.             UnLock(locks);
  447.             if (lockd)
  448.             UnLock(lockd);
  449.         }
  450.         }
  451.     } else if (sn->Fib[1]) {        /*    file/dir in dest-dir only */
  452. #ifdef DEBUG
  453.         puts("xupdate7");
  454. #endif
  455.         if (strncmp(sn->Fib[1]->fib_Comment, "DISTKEEP", 8) == 0) {
  456.         if (!Quiet)
  457.             puts("(KEEP)");
  458.         continue;
  459.         }
  460.         if (NoDel) {
  461.         if (!Quiet)
  462.             puts("(ignore)");
  463.         continue;
  464.         }
  465.         if (!Quiet)
  466.         puts("");
  467.  
  468.         if (sn->Fib[1]->fib_DirEntryType < 0) {    /*  file    */
  469.         if (getyn("File %s not in source tree,\ndelete from dest? ", sn->Node.ln_Name)) {
  470.             long savlock = (long)CurrentDir(dlock);
  471.             if (DeleteFile(sn->Node.ln_Name) == 0) {
  472.             SetProtection(sn->Node.ln_Name, 0);
  473.             if (DeleteFile(sn->Node.ln_Name) == 0)
  474.                 puts("(unable to delete)");
  475.             }
  476.             CurrentDir(savlock);
  477.         }
  478.         } else {
  479.         if (getyn("Dir %s not in source tree,\ndelete from dest? ", sn->Node.ln_Name)) {
  480.             long savlock = (long)CurrentDir(dlock);
  481.             DeleteDir(sn->Node.ln_Name);
  482.             CurrentDir(savlock);
  483.         }
  484.         }
  485.     }
  486. #ifdef DEBUG
  487.     puts("xupdate8");
  488. #endif
  489.  
  490.     }
  491.     tab -= 4;
  492. }
  493.  
  494. SNODE *
  495. SNodeIn(fib, list, side, ignm)
  496. FIB *fib;
  497. MLIST *list;
  498. int side;
  499. {
  500.     SNODE *sn;
  501.  
  502.     for (sn = GetHead(list); sn; sn = GetSucc(sn)) {
  503.     if (stricmp(fib->fib_FileName, sn->Node.ln_Name) == 0)
  504.         break;
  505.     }
  506.     if (sn == NULL) {
  507.     if (ignm)
  508.         return(NULL);
  509.     sn = malloc(sizeof(SNODE));
  510.     setmem(sn, sizeof(SNODE), 0);
  511.     NewList((LIST *)&sn->List);
  512.     AddTail((LIST *)list, (NODE *)sn);
  513.     }
  514.     if (sn->Fib[side] == NULL) {
  515.     sn->Fib[side] = malloc(sizeof(FIB));
  516.     setmem(sn->Fib[side], sizeof(FIB), 0);
  517.     }
  518.     *sn->Fib[side] = *fib;
  519.     if (sn->Node.ln_Name == NULL) {
  520.     sn->Node.ln_Name = malloc(strlen(fib->fib_FileName)+1);
  521.     strcpy(sn->Node.ln_Name, fib->fib_FileName);
  522.     }
  523.     return(sn);
  524. }
  525.  
  526. CheckBroke()
  527. {
  528.     if (Broke == 0 && SetSignal(0,SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D) & (SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D)) {
  529.     puts("ABORT");
  530.     Broke = 1;
  531.     }
  532.     return(Broke);
  533. }
  534.  
  535. getyn(s1, s2)
  536. char *s1, *s2;
  537. {
  538.     char buf[256];
  539.  
  540. #ifdef DEBUG
  541.     puts("gyn");
  542. #endif
  543.     for (;;) {
  544.     printf(s1, s2);
  545.     fflush(stdout);
  546.     if (gets(buf) == NULL)
  547.         return(0);
  548.     if (buf[0] == 'y' || buf[0] == 'Y')
  549.         return(1);
  550.     if (buf[0] == 'n' || buf[0] == 'N')
  551.         return(0);
  552.     puts("");
  553.     }
  554. }
  555.  
  556. CopyFile(sdir, ddir, sname, dname, dfib)
  557. long sdir, ddir;
  558. char *sname;
  559. char *dname;
  560. FIB *dfib;
  561. {
  562.     long Fhs = 0;
  563.     long Fhd = 0;
  564.     long savlock;
  565.     long bufsiz;
  566.     long n;
  567.     long r;
  568.     char *buf = NULL;
  569.     short error = 0;
  570.  
  571. #ifdef DEBUG
  572.     puts("xfile1");
  573.     printf("xfile1 %08lx %08lx %s %s %08lx\n", sdir, ddir, sname, dname, dfib);
  574. #endif
  575.     savlock = (long)CurrentDir(sdir);
  576. #ifdef DEBUG
  577.     puts("xfile2");
  578. #endif
  579.     Fhs = (long)Open(sname, 1005);
  580.     if (Fhs == NULL) {
  581.     printf("unable to open %s for read\n", sname);
  582.     error = 1;
  583.     goto fail;
  584.     }
  585. #ifdef DEBUG
  586.     puts("xfile3");
  587. #endif
  588.     CurrentDir(ddir);
  589. #ifdef DEBUG
  590.     puts("xfile4");
  591. #endif
  592.     Fhd = (long)Open(dname, 1006);
  593. #ifdef DEBUG
  594.     puts("xfile5");
  595. #endif
  596.     if (Fhd == NULL) {
  597.     SetProtection(dname, 0);
  598.     DeleteFile(dname);
  599.     Fhd = (long)Open(dname, 1006);
  600.     if (Fhd == NULL) {
  601.         printf("Unable to open %s for write\n", dname);
  602.         error = 1;
  603.         goto fail;
  604.     }
  605.     }
  606. #ifdef DEBUG
  607.     puts("xfile6");
  608. #endif
  609.     for (bufsiz = 32768; bufsiz; bufsiz >>= 1) {
  610.     if (buf = malloc(bufsiz))
  611.         break;
  612.     }
  613. #ifdef DEBUG
  614.     printf("bufsiz = %d\n", bufsiz);
  615. #endif
  616.     while ((n = Read(Fhs, buf, bufsiz)) > 0) {
  617.     r = Write(Fhd, buf, n);
  618.     if (r != n) {
  619.         puts("write failed");
  620.         error = 1;
  621.         goto fail;
  622.     }
  623.     }
  624. #ifdef DEBUG
  625.     puts("xfile7");
  626. #endif
  627. fail:
  628.     if (buf)
  629.     free(buf);
  630.     if (Fhs)
  631.     Close(Fhs);
  632.     if (Fhd)
  633.     Close(Fhd);
  634. #ifdef DEBUG
  635.     puts("xfile8");
  636. #endif
  637.     if (error)
  638.     SetProtection(dname, dfib->fib_Protection & ~(FIBF_READ|FIBF_WRITE));
  639.     else
  640.     SetProtection(dname, dfib->fib_Protection);
  641. #ifdef DEBUG
  642.     puts("xfile9");
  643. #endif
  644.     SetFileDate(dname, &dfib->fib_Date);
  645.     if (dfib->fib_Comment[0])
  646.     SetComment(dname, dfib->fib_Comment);
  647.     CurrentDir(savlock);
  648. #ifdef DEBUG
  649.     puts("xfile10");
  650. #endif
  651.  
  652. }
  653.  
  654. DeleteDir(name)
  655. char *name;
  656. {
  657.     FIB *fib = malloc(sizeof(FIB));
  658.     long lock = (long)Lock(name, ACCESS_READ);
  659.  
  660.     if (lock) {
  661.     if (Examine(lock, fib) && fib->fib_DirEntryType > 0) {
  662.         long savdir = (long)CurrentDir(lock);
  663.         while (ExNext(lock, fib))
  664.         DeleteDir(fib->fib_FileName);
  665.         CurrentDir(savdir);
  666.     }
  667.     UnLock(lock);
  668.     if (DeleteFile(name) == 0) {
  669.         SetProtection(name, 0);
  670.         DeleteFile(name);
  671.     }
  672.     }
  673.     free(fib);
  674. }
  675.  
  676. NODE *
  677. FindNode(list, name)
  678. LIST *list;
  679. char *name;
  680. {
  681.     NODE *node;
  682.  
  683.     for (node = GetHead(list); node; node = GetSucc(node)) {
  684.     if (stricmp(node->ln_Name, name) == 0)
  685.         return(node);
  686.     }
  687.     return(NULL);
  688. }
  689.  
  690.